package com.yanqu.road.server.manager.activity.musicroomrank;

import com.yanqu.road.dao.impl.activity.musicroomrank.CrossMusicRoomRankRoundDaoImpl;
import com.yanqu.road.dao.impl.activity.musicroomrank.CrossMusicRoomRankShowDaoImpl;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.musicroomrank.CrossMusicRoomRankRoundData;
import com.yanqu.road.entity.activity.musicroomrank.CrossMusicRoomRankShowData;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.rank.cross.CrossUserRank;
import com.yanqu.road.logic.activity.musicroomrank.MusicRoomRankConfig;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.pb.activity.MusicRoomRankProto;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.activity.ActivityRankMgr;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.date.DateHelper;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

public class MusicRoomRankActivity {
    private ActivityInfo activityInfo;
    private MusicRoomRankShowRoom nowRoom = null;
    private AtomicInteger maxRound = new AtomicInteger(0);

    /**
     * 等待结算的场次
     */
    private List<MusicRoomRankShowRoom> waitSettleRoom = new ArrayList<>();
    /**
     * 历史演出数据
     */
    private List<MusicRoomRankHistoryShowRoom> historyShowRoomList = new ArrayList<>();
    private Map<Integer, MusicRoomRankHistoryShowRoom> historyShowRoomMap = new HashMap<>();
    /**
     * 玩家的总分
     */
    private Map<Long, Long> userTotalScoreMap = new ConcurrentHashMap<>();

    /**
     * 等待检查更新入库的room
     */
    private List<MusicRoomRankShowRoom> waitUpdateSqlRoomList = new ArrayList<>();

    public MusicRoomRankActivity(ActivityInfo activityInfo) {
        this.activityInfo = activityInfo;
        loadDb();
    }

    public MusicRoomRankConfig getConfig() {
        return CrossMusicRoomRankConfigMgr.getConfig(activityInfo.getActivityId());
    }

    public void loadDb() {
        List<CrossMusicRoomRankRoundData> tempRoundDataList = new CrossMusicRoomRankRoundDaoImpl().getCrossMusicRoomRankRoundList(activityInfo.getActivityId(), getConfig().getMaxHistoryShowNum() + 1);
        Map<Integer, List<CrossMusicRoomRankShowData>> tempShowDataMap = new CrossMusicRoomRankShowDaoImpl().getShowDataMap(activityInfo.getActivityId());

        int tempMaxRound = 0;
        List<MusicRoomRankHistoryShowRoom> tempHistoryShowRoomList = new ArrayList<>();
        MusicRoomRankShowRoom tempShowRoom = null;
        for (CrossMusicRoomRankRoundData roundData : tempRoundDataList) {
            if (roundData.getFinishTime() > 0) {
                MusicRoomRankHistoryShowRoom historyShowRoom = new MusicRoomRankHistoryShowRoom(roundData, tempShowDataMap.getOrDefault(roundData.getRound(), new ArrayList<>()));
                tempHistoryShowRoomList.add(historyShowRoom);
            } else {
                MusicRoomRankShowRoom showRoom = new MusicRoomRankShowRoom(this, roundData, tempShowDataMap.getOrDefault(roundData.getRound(), new ArrayList<>()));
                tempShowRoom = showRoom;
            }

            if (roundData.getRound() > tempMaxRound) {
                tempMaxRound = roundData.getRound();
            }
        }

        tempHistoryShowRoomList.sort((o1, o2) -> {
            int compare = Integer.compare(o1.getRound(), o2.getRound());
            return compare;
        });

        nowRoom = tempShowRoom;

        for (MusicRoomRankHistoryShowRoom historyShowRoom : tempHistoryShowRoomList) {
            addHistoryShowRoom(historyShowRoom);
            addUserTotalRankScore(historyShowRoom, true);
        }
        for (MusicRoomRankHistoryShowRoom musicRoomRankHistoryShowRoom : historyShowRoomList) {
            historyShowRoomMap.put(musicRoomRankHistoryShowRoom.getRound(), musicRoomRankHistoryShowRoom);
        }
        maxRound.set(tempMaxRound);


    }

    public synchronized MusicRoomRankProto.MusicRoomRankMainSceneRespMsg.Builder getMainSceneMsg() {
        MusicRoomRankConfig config = getConfig();
        if (config == null) {
            return MusicRoomRankProto.MusicRoomRankMainSceneRespMsg.newBuilder().setRet(GameErrorCode.E_ACTIVITY_NOT_OPEN);
        }
        if (!config.isInOpenTime()) {
            return MusicRoomRankProto.MusicRoomRankMainSceneRespMsg.newBuilder().setRet(GameErrorCode.E_ACTIVITY_NOT_OPEN);
        }
        checkRoomEnd();
        return nowRoom.getMainSceneMsg();
    }

    private MusicRoomRankShowRoom createNewRoom() {
        int theme = getConfig().randomTheme();
        CrossMusicRoomRankRoundData roundData = new CrossMusicRoomRankRoundData(activityInfo.getActivityId(), maxRound.incrementAndGet(), theme, DateHelper.getCurrentSecond());
        return new MusicRoomRankShowRoom(this, roundData, new ArrayList<>());
    }

    /**
     * 历史参赛记录
     */
    public MusicRoomRankProto.MusicRoomRankHistoryShowRespMsg.Builder getHistoryShowList(long userId) {
        MusicRoomRankProto.MusicRoomRankHistoryShowRespMsg.Builder builder = MusicRoomRankProto.MusicRoomRankHistoryShowRespMsg.newBuilder();
        builder.setRet(0);
        for (MusicRoomRankHistoryShowRoom historyShowRoom : historyShowRoomList) {
            builder.addHistoryData(historyShowRoom.getRoundTemp());
            if (historyShowRoom.isUserJoined(userId)) {
                builder.addOwnJoinRound(historyShowRoom.getRound());
            }
        }
        return builder;
    }

    /**
     * 获得历史比赛详情
     */
    public MusicRoomRankProto.MusicRoomRankHistoryShowDetailRespMsg.Builder getHistoryShowDetail(long userId, int round) {
        MusicRoomRankProto.MusicRoomRankHistoryShowDetailRespMsg.Builder builder = MusicRoomRankProto.MusicRoomRankHistoryShowDetailRespMsg.newBuilder();
        builder.setRet(0);
        if (!historyShowRoomMap.containsKey(round)) {
            return builder.setRet(GameErrorCode.E_MUSIC_ROOM_RANK_NOT_ROUND);
        }
        MusicRoomRankHistoryShowRoom historyShowRoom = historyShowRoomMap.get(round);
        builder.addAllHistoryData(historyShowRoom.getShowTempList());
        builder.setRankScore(historyShowRoom.getUserRankScore(userId));
        return builder;
    }

    /**
     * 参赛
     */
    public synchronized MusicRoomRankProto.CrossMusicRoomRankJoinShowBackMsg.Builder joinShow(long userId, int round, int beautyId, int skinId, List<Long> attrList, int cardUsedAmount, String cost) {
        checkRoomEnd();
        MusicRoomRankProto.CrossMusicRoomRankJoinShowBackMsg.Builder builder = MusicRoomRankProto.CrossMusicRoomRankJoinShowBackMsg.newBuilder();
        builder.setActivityId(activityInfo.getActivityId());
        builder.setRet(0);
        if (nowRoom.getRound() != round) {
            return builder.setRet(GameErrorCode.E_MUSIC_ROOM_RANK_ROUND_END);
        }
        int ret = nowRoom.joinShow(userId, beautyId, skinId, attrList, cardUsedAmount, cost);
        builder.setRet(ret);
        builder.setBeautyId(beautyId);
        builder.setSkinId(skinId);
        builder.setRound(round);

        checkRoomEnd();
        return builder;
    }

    /**
     * 时辰卡累计使用同步
     */
    public synchronized void syncCardUsed(long userId, int amount) {
        if (nowRoom != null) {
            nowRoom.syncCardUsed(userId, amount);
        }
    }

    /**
     * 时间到或者人数满足时开始选拔
     */
    public synchronized void checkRoomEnd() {
        if (nowRoom == null) {
            nowRoom = createNewRoom();
            return;
        }
        if (nowRoom.isFull() || nowRoom.isTimeEnd()) {
            waitSettleRoom.add(nowRoom);
            nowRoom = null;
        }
    }

    /**
     * 定时器结算
     */
    public synchronized void settleTask() {
        if (nowRoom != null) {
            if (nowRoom.isFull() || nowRoom.isTimeEnd()) {
                waitSettleRoom.add(nowRoom);
                nowRoom = null;
            }
        }

        if (waitSettleRoom.isEmpty()) {
            return;
        }
        List<MusicRoomRankShowRoom> tempWaitSettleRoom = new ArrayList<>();
        tempWaitSettleRoom.addAll(waitSettleRoom);
        waitSettleRoom.clear();

        for (MusicRoomRankShowRoom room : tempWaitSettleRoom) {
            // 结算
            MusicRoomRankHistoryShowRoom historyShowRoom = room.settle();
            addHistoryShowRoom(historyShowRoom);

            //榜单更新
            addUserTotalRankScore(historyShowRoom, false);

            // 添加等待同步的游戏服
            historyShowRoom.addSyncResultMsgMap();
            syncRoomSettle(historyShowRoom);

            synchronized (waitUpdateSqlRoomList) {
                waitUpdateSqlRoomList.add(room);
            }
        }
    }

    /**
     * 同步评选结果到游戏服
     */
    private void syncRoomSettle(MusicRoomRankHistoryShowRoom historyShowRoom) {
        Map<Long, MusicRoomRankProto.CrossMusicRoomRankShowResultResultMsg.Builder> serverMsgMap = historyShowRoom.getSyncResultMsgMap();
        for (Map.Entry<Long, MusicRoomRankProto.CrossMusicRoomRankShowResultResultMsg.Builder> entry : serverMsgMap.entrySet()) {
            Long serverId = entry.getKey();
            MusicRoomRankProto.CrossMusicRoomRankShowResultResultMsg.Builder syncMsg = entry.getValue();
            YanQuMessage yanQuMessage = YanQuMessageUtils.buildMessage(GameProtocol.S_MUSIC_ROOM_RANK_SHOW_RESULT_CROSS_BACK, syncMsg.build());
            MessageHelper.sendPacket(serverId, 0, yanQuMessage);
        }
    }

    /**
     * 游戏服返回确认结果同步
     */
    public void syncRoomSettleConfirmBack(long serverId, int round) {
        MusicRoomRankHistoryShowRoom historyShowRoom = historyShowRoomMap.get(round);
        if (historyShowRoom == null) {
            CrossMusicRoomRankActivityMgr.getLogger().error("syncRoomSettleBack error, round not exist, serverId:{}, round:{}", serverId, round);
            return;
        }
        historyShowRoom.removeSyncResultMsgMap(serverId);
    }

    private void addHistoryShowRoom(MusicRoomRankHistoryShowRoom historyShowRoom) {
        synchronized (historyShowRoomList) {
            historyShowRoomMap.put(historyShowRoom.getRound(), historyShowRoom);
            historyShowRoomList.add(historyShowRoom);
            if (historyShowRoomList.size() > getConfig().getMaxHistoryShowNum()) {
                MusicRoomRankHistoryShowRoom tempHistoryRoom = historyShowRoomList.get(0);
                historyShowRoomList.remove(0);
                historyShowRoomMap.remove(tempHistoryRoom.getRound());
            }
        }
    }

    public void save() {
        if (nowRoom != null) {
            nowRoom.save();
        }

        List<MusicRoomRankShowRoom> saveList = new ArrayList<>();
        synchronized (waitUpdateSqlRoomList) {
            saveList.addAll(waitUpdateSqlRoomList);
            waitUpdateSqlRoomList.clear();
        }

        for (MusicRoomRankShowRoom room : saveList) {
            room.save();
        }

        List<MusicRoomRankHistoryShowRoom> saveHistoryRoomList = new ArrayList<>();
        synchronized (historyShowRoomList) {
            saveHistoryRoomList.addAll(historyShowRoomList);
        }

        long currentSecond = DateHelper.getCurrentTime() / 1000;
        for (MusicRoomRankHistoryShowRoom historyShowRoom : saveHistoryRoomList) {
            historyShowRoom.save();
            //结束60秒后才额外检查同步
            if (!historyShowRoom.isAllSyncBack() && currentSecond - historyShowRoom.getRoundTemp().getEndTime() > 60) {
                syncRoomSettle(historyShowRoom);
            }
        }

    }

    public void addUserTotalRankScore(MusicRoomRankHistoryShowRoom historyShowRoom, boolean isInit) {
        for (Map.Entry<Long, Long> entry : historyShowRoom.getUserRankScoreMap().entrySet()) {
            Long userId = entry.getKey();
            Long rankScoreAdd = entry.getValue();

            Long oldTotalScore = userTotalScoreMap.getOrDefault(userId, 0L);
            userTotalScoreMap.put(userId, oldTotalScore + rankScoreAdd);

            if (!isInit) {
                updateUserRank(userId);
            }
        }
    }

    public void updateUserRank(long userId) {
        //需求变动,榜单积分改到游戏服变动
//        CrossUserRank crossUserRank = new CrossUserRank();
//        crossUserRank.setUserId(userId);
//        crossUserRank.setValue(BigInteger.valueOf(userTotalScoreMap.getOrDefault(userId, 0L)));
//        crossUserRank.setType(activityInfo.getActivityId());
//        crossUserRank.setBigRankType(eGamePlayerEventType.MusicRoomScoreRank.getValue());
//        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
//        if (userBaseInfo != null) {
//            crossUserRank.setUserBaseInfo(userBaseInfo);
//        }
//        ActivityRankMgr.changeActivityNewRank(activityInfo.getActivityId(), eGamePlayerEventType.MusicRoomScoreRank.getValue(), crossUserRank);
//
//        ActivityRankMgr.changeUserRank(activityInfo.getActivityId(), crossUserRank);
    }

}
